# !/usr/bin/env python
# -*- encoding: utf-8 -*-
# @Author : 大野
'''
定时任务
'''
import json
import time

from common.log import Log
from flask import request, jsonify
import datetime
from flask_apscheduler import APScheduler
from interface.testCase.interfaceTest import Testtest
from interface.model.casetaskSql import casetasksql
from common.database import DataBase
from common.timeJson import ComplexEncoder
from apscheduler.schedulers.background import BackgroundScheduler

db = DataBase()
cs = casetasksql()
logging = Log()

# scheduler = APScheduler()
scheduler = BackgroundScheduler(daemon=True)


def pausetask():  # 暂停
    id = request.args.get("id")
    scheduler.pause_job(id)
    __update_status(id, 2)
    return {"code": 1}


def resumetask():  # 恢复
    id = request.args.get("id")
    scheduler.resume_job(id)
    __update_status(id, 1)
    return {"code": 1}


def remove_task():  # 移除
    try:
        id = request.args.get("id")
        scheduler.remove_job(id, jobstore='')
        __update_status(id, 0)
        return {"code": 1}
    except Exception as e:
        return {"code": 0, "msg": str(e)}


def start_task():
    """启动任务"""
    id = request.args.get("id")
    result = __task_body(id)
    r = datetime.datetime.now()
    res = r.strftime("%Y-%m-%d %H:%M:%S")
    print(type(result['end_time']), type(res))
    if str(result['end_time']) >= res:

        try:
            if result['data_format'] == 'minutes':
                __minutes(result)
            elif result['data_format'] == 'hours':
                __hours(result)
            elif result['data_format'] == 'days':
                __days(result)
            scheduler.start()
            __update_status(id, 1)
            return {"code": 1}
        except Exception as e:
            return {"code": 0, "msg": f"操作失败了，为什么？如下{e}"}
    else:
        return {"code": 0, "msg": f"启动失败，结束时间小于当前时间，如下{result['end_time']}"}


def operation_case():
    """手动操作任务用例"""
    id = request.args.get("id")
    result = __task_body(id)
    resp = __task_job(id, result['project_name'])
    return jsonify(resp)


def __task_body(id):
    sql = f'select * from task_time where id={id}'
    data = db.test_platform([sql])
    return data[0]


def __minutes(data):
    return scheduler.add_job(func=__task_job, id=f"{data['id']}", args=[f"{data['id']}", f"{data['project_name']}"],
                             trigger='interval',
                             start_date=str(data["start_time"]),
                             end_date=str(data["end_time"]), minutes=int(f'{data["number"]}'), replace_existing=True)


def __hours(data):
    return scheduler.add_job(func=__task_job, id=f"{data['id']}", args=[f"{data['id']}", f"{data['project_name']}"],
                             trigger='interval',
                             start_date=str(data["start_time"]),
                             end_date=str(data["end_time"]), hours=int(f'{data["number"]}'), replace_existing=True)


def __days(data):
    return scheduler.add_job(func=__task_job, id=f"{data['id']}", args=[f"{data['id']}", f"{data['project_name']}"],
                             trigger='interval',
                             start_date=str(data["start_time"]),
                             end_date=str(data["end_time"]), days=int(f'{data["number"]}'), replace_existing=True)


def __task_job(id, project_name):
    from interface.model.combinationSql import ServiceVersion
    sv = ServiceVersion()
    global project, resp
    try:
        casesuite = __get_case(id)
        sql = f"select * from project_info where project_name = '{project_name}'"
        project = db.test_platform([sql])
        resp = Testtest().testInterface(project[0]['id'], casesuite)
        return resp
    except Exception as e:
        logging.error(f"定时任务执行异常【{e}】")
    # finally:
    #     from interface.view.apicommon import save_case_log
    #     sql = f"select * from task_data where task_id = '{id}'"
    #     versions = db.test_platform([sql])
    #     data = listdata(versions, project[0]['id'])
    #     save_case_log(sv, data, db, resp)


def __get_case(task_id):
    sql = cs.select_task_case(task_id)
    casesuite = db.test_platform(sql)
    return casesuite


def __update_status(task_id, status):
    sql = cs.update_task_status(task_id, status)
    db.test_platform(sql, m='w')
    return True


class casetask:
    def select_task(self):
        project_name = request.args.get('name')
        sql = cs.select_task(project_name)
        result = db.test_platform(sql)
        return json.dumps(result, cls=ComplexEncoder)

    def select_sv(self):
        project_name = request.args.get('name')
        sql = cs.select_sv(project_name)
        result = db.test_platform(sql)
        res = dictdata(result)
        return jsonify(res)

    def add_task(self):
        """创建任务"""
        data = json.loads(request.data)
        try:
            tasksql = cs.add_task(data)
            res = db.test_platform(tasksql, m='w')
            if res["code"] == 1:
                service_version = data["service_version"]
                sv_sql = cs.add_task_sv(service_version, res['id'])
                db.test_platform(sv_sql, m='w')
                return {"success": 'true'}
        except Exception as e:
            return {"success": 'false', 'massage': str(e)}

    def delete_task(self):
        """删除任务"""
        id = request.args.get("id")
        try:
            tasksql = [f"DELETE from task_time where id ={id};", f"DELETE from task_data where task_id={id};"]
            res = db.test_platform(tasksql, m='w')
            if res["code"] == 1:
                return {"success": True, "msg": "删除成功"}
        except Exception as e:
            return {"success": False, 'massage': str(e)}


casetask = casetask()

from functools import reduce


def dictdata(result):
    '''
    创建定时任务的版本号
    用来重新组合字典
    :param result:
    :return:
    '''
    rests = []
    restse = []
    for res in result:
        rest = {}
        rest["id"] = res["service_id"]
        rest["name"] = res["service_name"]
        rests.append(rest)
    filter_function = lambda x, y: x if y in x else x + [y]
    test = reduce(filter_function, [[], ] + rests)
    for i in test:
        version = []
        for j in result:
            versiondict = {}
            if i["id"] == j["service_id"]:
                versiondict["id"] = j["version_id"]
                versiondict["name"] = j["version_name"]
                version.append(versiondict)
        i["version"] = version
        restse.append(i)
    return restse


def listdata(result, project):
    '''存储定时任务产生的报告'''
    global i
    versions = []
    if isinstance(result, list):
        for i in result:
            for k, v in i.items():
                if k == 'version_id':
                    versions.append(v)
                    break
        i.update({"version_id": str(versions), "project_id": project})
        return i
